package com.suning.sawp.service.impl.util;

import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import net.oss.client.OSSClient;
import net.oss.client.OSSClientImpl;
import net.oss.result.SdossResult;
import net.oss.util.Sdoss_Head_Util;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.constants.ExportConstants;
import com.suning.sawp.intf.util.OSSFileService;
import com.suning.sawp.po.util.OSSFileResult;

/**
 * 
 * 〈一句话功能简述〉OSS工具Service<br>
 * OSS文件存储工具类 API ：http://wiki.cnsuning.com/pages/viewpage.action?pageId=27238154
 * 平台：http://osspsit.cnsuning.com/snoss-web/ http://osspprd.cnsuning.com/snoss-web/
 *
 * @author 17033093
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
public class OSSFileServiceImpl implements OSSFileService {

    private static final Logger LOGGER = LoggerFactory.getLogger(OSSFileServiceImpl.class);

    /**
     * 成功
     */
    private static final String SUCCESS = "1";

    /**
     * 失败
     */
    private static final String FAILED = "0";

    /**
     * oss配置文件地址
     */
    @Value("#{settingConfig[oss_config_path]}")
    String OSS_CONFIG_PATH;

    @Override
    public OSSFileResult upload2OSSByFile(String bucketName, String objectName, File file) {
        LOGGER.info("upload2OSSByFile. bucketName:{}, objectname:{}", bucketName, objectName);

        if (StringUtils.isBlank(objectName) || null == file) {
            return new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E004, "文件上传参数不合法");
        }

        // 设置默认BUCKET
        String bucketNameInput = StringUtils.isBlank(bucketName) ? ExportConstants.OSSFileParams.BUCKET_EXPORT : bucketName;

        OSSClient client = new OSSClientImpl(false, OSS_CONFIG_PATH);
        Map<String, String> headerArgument = new HashMap<String, String>();
        try {
            // 设置有效期
            headerArgument.put(Sdoss_Head_Util.Cycle, ExportConstants.OSSFileParams.FILE_CYCLE_TIME);
            // 获取鉴权
            SdossResult authorityReturn = client.putObject(bucketNameInput, objectName, headerArgument);
            if (authorityReturn != null && authorityReturn.isSuccess()) {
                // objectname必须和生成签名时一致
                String url = authorityReturn.getFileraddr() + "/" + authorityReturn.getAccount_id() + "/"
                        + bucketNameInput + "/" + objectName;
                // 上传文件
                SdossResult result = client.putObject(file, headerArgument, authorityReturn.getAuthorization(),
                        authorityReturn.getCurrent_time(), url);

                if (result.isSuccess()) {
                    // 获取下载URL
                    String returnUrl = authorityReturn.getFileraddr() + "/" + authorityReturn.getAccount_id() + "/"
                            + bucketNameInput + "/" + result.getObjectId();
                    return new OSSFileResult(SUCCESS, returnUrl);
                } else {
                    LOGGER.error("upload2OSSByFile.putObject error for upload:{}, objectname:{}, result:{}",
                            bucketName, objectName, result);
                    return new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E006, "上传文件失败");
                }
            } else {
                LOGGER.error("upload2OSSByFile.authority error for bucket:{}, objectname:{}, authorityReturn:{}",
                        bucketName, objectName, authorityReturn);
                return new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E005, "获取bucket鉴权失败");
            }
        } catch (Exception e) {
            LOGGER.error("upload2OSSByFile failed.", e);
            return new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E999, "系统繁忙，请稍后重试");
        }

    }
    
    @Override
    public OSSFileResult upload2OSSByFile(String bucketName, String objectName, File file, String cycleTime) {
        LOGGER.info("upload2OSSByFile. bucketName:{}, objectname:{}, cycleTime:{}", bucketName, objectName, cycleTime);

        if (StringUtils.isBlank(objectName) || null == file) {
            return new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E004, "文件上传参数不合法");
        }

        // 设置默认BUCKET
        String bucketNameInput = StringUtils.isBlank(bucketName) ? ExportConstants.OSSFileParams.BUCKET_EXPORT : bucketName;

        OSSClient client = new OSSClientImpl(false, OSS_CONFIG_PATH);
        Map<String, String> headerArgument = new HashMap<String, String>();
        try {
            // 若有效期不是数字，则默认设置为一天
            if (!StringUtils.isNumeric(cycleTime)) {
                cycleTime = ExportConstants.OSSFileParams.FILE_CYCLE_TIME;
            }
            // 设置有效期
            headerArgument.put(Sdoss_Head_Util.Cycle, cycleTime);
            // 获取鉴权
            SdossResult authorityReturn = client.putObject(bucketNameInput, objectName, headerArgument);
            if (authorityReturn != null && authorityReturn.isSuccess()) {
                // objectname必须和生成签名时一致
                String url = authorityReturn.getFileraddr() + "/" + authorityReturn.getAccount_id() + "/"
                        + bucketNameInput + "/" + objectName;
                // 上传文件
                SdossResult result = client.putObject(file, headerArgument, authorityReturn.getAuthorization(),
                        authorityReturn.getCurrent_time(), url);

                if (result.isSuccess()) {
                    // 获取下载URL
                    String returnUrl = authorityReturn.getFileraddr() + "/" + authorityReturn.getAccount_id() + "/"
                            + bucketNameInput + "/" + result.getObjectId();
                    return new OSSFileResult(SUCCESS, returnUrl);
                } else {
                    LOGGER.error("upload2OSSByFile.putObject error for upload:{}, objectname:{}, result:{}",
                            bucketName, objectName, result);
                    return new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E006, "上传文件失败");
                }
            } else {
                LOGGER.error("upload2OSSByFile.authority error for bucket:{}, objectname:{}, authorityReturn:{}",
                        bucketName, objectName, authorityReturn);
                return new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E005, "获取bucket鉴权失败");
            }
        } catch (Exception e) {
            LOGGER.error("upload2OSSByFile failed.", e);
            return new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E999, "系统繁忙，请稍后重试");
        }

    }

    @Override
    public OSSFileResult upload2OSSByStream(String bucketName, String objectName, String mimeType, InputStream in) {

        OSSFileResult rsp = new OSSFileResult();

        LOGGER.info("authority error for bucket :{},objectname :{} ", bucketName, objectName);
        if (StringUtils.isBlank(objectName)) {
            return new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E004, "文件上传参数不合法");
        }

        // 设置默认BUCKET
        String bucketnameInput = StringUtils.isBlank(bucketName) ? ExportConstants.OSSFileParams.BUCKET_EXPORT : bucketName;

        OSSClient client = new OSSClientImpl(false, OSS_CONFIG_PATH);
        Map<String, String> headerArgument = new HashMap<String, String>();
        try {
            // 设置有效期
            headerArgument.put(Sdoss_Head_Util.Cycle, ExportConstants.OSSFileParams.FILE_CYCLE_TIME);
            // 获取鉴权
            SdossResult authorityReturn = client.putObject(bucketnameInput, objectName, headerArgument);
            
            if (authorityReturn != null && authorityReturn.isSuccess()) {
                // objectname必须和生成签名时一致
                String url = authorityReturn.getFileraddr() + "/" + authorityReturn.getAccount_id() + "/" + bucketnameInput
                        + "/" + objectName;
                // 上传文件
                SdossResult result = client.putObject(in, objectName, mimeType, headerArgument,
                        authorityReturn.getAuthorization(), authorityReturn.getCurrent_time(), url);
                if (result.isSuccess()) {
                    // 获取下载URL
                    String returnUrl = authorityReturn.getFileraddr() + "/" + authorityReturn.getAccount_id() + "/"
                            + bucketnameInput + "/" + result.getObjectId();
                    rsp = new OSSFileResult(SUCCESS, returnUrl);
                } else {
                    LOGGER.error("putObject error for bucket :{},objectname :{} ", bucketName, objectName);
                    rsp = new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E006, "上传文件失败");
                }
            } else {
                LOGGER.error("authority error for bucket :{},objectname :{} ", bucketName, objectName);
                rsp = new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E005, "获取bucket鉴权失败");
            }
        } catch (Exception e) {
            LOGGER.error("authority exception ", e);
            rsp = new OSSFileResult(FAILED, ErrorCodeConstants.EXPORT_ERR_E999, "系统繁忙，请稍后重试");
        } finally {
            IOUtils.closeQuietly(in);
        }
        return rsp;
    }
}
